import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
/* Ori Perl
 * 10/6/10
 * Software Design pd. 8
 * This program creates a game in which Mr. Walstein destroys calculators with his mind. It keep tracks of when
 * calculators are smashed in form of points.
 * 
 * */



public class SmashTime extends JPanel implements MouseInputListener{
	private MediaTracker tracker;
	private Image world, mouse,back;
	private Image redCalc, blackCalc, silverCalc, boom;
	private AnimThread animator;
	Desk[][] desks = new Desk[3][2];
	ArrayList <Calculator> calcs;
	BufferedImage off;
	int combo = 0;
	int cTime = 0;
	int score = 0;
	int time = 0;
	int speedMove = 100;
	int speedGen = 60;
	/*speed:
	 * 	move:
	 * 		easy = 100
	 * 		medium = 50
	 * 		hard = 16
	 *  generation:
	 * 		easy = 60
	 * 		medium = 40
	 * 		hard = 16 
	 */
	Cursor cursor;
	//for testing purposes;
	public static void main(String args[]) {
		final SmashTime smash = new SmashTime();
		JFrame app = new JFrame();
		app.add(smash, BorderLayout.CENTER);
		app.setSize(1024,800);
		app.setVisible(true);
		app.setResizable(false);
	}//end main
	
	public SmashTime(){
		calcs = new ArrayList <Calculator>();
		setSize(1024,800);
		tracker = new MediaTracker(this);
		addMouseListener(this);
		Toolkit toolkit = Toolkit.getDefaultToolkit();
	    back = toolkit.getImage("fg_evil_monkey.jpg");
	    //will vary once graphics guy gives me the image
	    redCalc = toolkit.getImage("images.jpg");
	    silverCalc = toolkit.getImage("images.jpg");
	    blackCalc = toolkit.getImage("images.jpg");
	    boom = toolkit.getImage("boom.jpg");
	    tracker.addImage(back,0);
	    tracker.addImage(redCalc,1);
	    tracker.addImage(silverCalc,2);
	    tracker.addImage(blackCalc,3);
	    tracker.addImage(boom,4);
		try {
			tracker.waitForAll();  // wait for images to fully load
		}//end try
		catch(InterruptedException e){
			
		}//end catch
		addMouseListener(new MouseCursorListener());
		addMouseMotionListener(new MouseCursorListener());
		animator = new AnimThread();
		
		//instantiate the array of desks
		//points will change once graphics person makes graphics and knows where actually desks are
		desks[0][0] = new Desk (new Point(250,50), new Point(450,200));
		desks[0][1] = new Desk (new Point(600,50), new Point(800,200));
		desks[1][0] = new Desk (new Point(250,250), new Point(450,400));
		desks[1][1] = new Desk (new Point(600,250), new Point(800,400));
		desks[2][0] = new Desk (new Point(250,450), new Point(450,600));
		desks[2][1] = new Desk (new Point(600,450), new Point(800,600));
		desks[2][0].addCalc(1);
		animator.start();
	}//end constructor

	
	public void paint(Graphics g) {
		update(g);
	}//end paint
	private class MouseCursorListener extends MouseInputAdapter
	{
	public void mouseEntered(MouseEvent e)
	{
	// Set cursor for the frame component
	setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
	
	}//end mouse entered
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
	}
	}
	
	public void update(Graphics g) { 
		Graphics2D g2 = (Graphics2D)(g);
		if (off == null)
			 off = new BufferedImage(getWidth(), getHeight(), 	BufferedImage.TYPE_INT_RGB);
		Graphics2D bg2 = (Graphics2D) off.getGraphics();
		//bottom section
		bg2.drawImage(back, 0,0,  this);
	
		//draws the time the time changes every second because time is in miliseconds
		bg2.drawString("Time: "+time/1000, 30, 30);
		
		//draws the score
		bg2.drawString("Score: "+score, 700, 30);
		
		//draws the combo
		if(combo >1){
			bg2.drawString("Combo: 100* "+ (combo-1), 800, 30);
		}//end if
		
		//divided into 4 sections. i will draw below each if I want to hide a calculator
		//3rd section
		for (int i = 0; i <2; i++){
			Calculator calc = desks[0][i].getCalc();
			if (calc != null && !calc.isHit()){
				//checks for color of calculator
				if (calc.getColor()==1){
					bg2.drawImage(redCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end if
				else if (calc.getColor()==2){
					bg2.drawImage(blackCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				else if (calc.getColor()==3){
					bg2.drawImage(blackCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				desks[0][i].moveCalc();
				//for speeding up, it moves the calculator more often to speed it up
				if (time %(speedMove) ==0){
					desks[0][i].moveCalc();
				}//end if
			}//end if
		}//end for 
		bg2.drawImage(back, 0, 200, this);
		
		
		
		for (int i = 0; i <2; i++){
			if (desks[1][i].getCalc() != null && !desks[1][i].getCalc().isHit()){
				Calculator calc = desks[1][i].getCalc();
				//checks for color of calculator
				if (calc.getColor()==1){
					bg2.drawImage(redCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end if
				else if (calc.getColor()==2){
					bg2.drawImage(blackCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				else if (calc.getColor()==3){
					bg2.drawImage(blackCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				desks[1][i].moveCalc();
				//for speeding up, it moves the calculator more often to speed it up
				if (time %(speedMove) ==0){
					desks[1][i].moveCalc();
				}//end if
			}//end if
		}//end for 
		
		//2nd section
		bg2.drawImage(back, 0, 400, this);
		
		
		for (int i = 0; i <2; i++){
			Calculator calc = desks[2][i].getCalc();
			if (calc != null && !calc.isHit()){
				//checks for color of calculator
				if (calc.getColor()==1){
					bg2.drawImage(redCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end if
				else if (calc.getColor()==2){
					bg2.drawImage(blackCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				else if (calc.getColor()==3){
					bg2.drawImage(silverCalc, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end else if
				desks[2][i].moveCalc();
				//for speeding up, it moves the calculator more often to speed it up
				if (time %(speedMove) ==0){
					desks[2][i].moveCalc();
				}//end if
			}//end if
		}//end for 
		//top section
		bg2.drawImage(back, 0, 600, this);
		
		
		//draw the explosions so they are on top of all images
		for (int i = 0; i <3; i++){
			for (int j = 0; j <2; j++){
				if (desks[i][j].getCalc() != null && desks[i][j].getCalc().isHit()){
					Calculator calc = desks[i][j].getCalc();
					desks[i][j].moveCalc();
					bg2.drawImage(boom, (int)calc.getBottomLeft().getX(),(int)calc.getTopRight().getY(),  this);
				}//end if
			}//end for
		}//end for
		
		//draws everything onto the screen
		g2.drawImage(off,0,0,this);
	}//end update
	
	



	class AnimThread extends Thread {
		int rand ;
		int i;
		int j;
		public void run() {
			while (Thread.currentThread() == animator) {
				time +=1;
				//random calc generation
				if (time%(speedGen*10+200) == 20){
					i= 0;
					j=0;
					rand = (int) (Math.random()*100);
					int count = 0;
					if (rand >6){
						do{
							count++;
							i = (int) (Math.random()*3);
							j = (int) (Math.random()*2);
						}while (desks[i][j].getCalc()!=null && count < 6);
						if(count <6){
							desks[i][j].addCalc((int)(Math.random()*3)+1);
						}//end if						
					}//end if
					
				}//end if
				if (time%10000==0){
					if (speedMove/2 >0)
						speedMove/=2;
					if (speedGen-5>0){
						speedGen-=5;
					}//end if					]
				}//end if
				//ends program after a minute
				if (time > 60000){
					//adds score from remaining combos
					score += (combo-1) *100;
					System.out.println(score);
					System.exit(0);
				}//end if
			repaint();
			
			try {
				throw new InterruptedException();
			}
			catch (InterruptedException e){
			}
			finally {try {
				animator.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}}
		 }
		}
		
	
	}

	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}//mouse clicked

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		boolean hit = false;
		for (int i = 0; i <3; i++){
			for (int j = 0; j <2; j++){
				if (desks[i][j].hasCalc(e.getPoint())){
					score +=desks[i][j].getCalc().getPoints();
					hit = true;
					if(time-cTime<800){
						cTime = time;
						combo++;
					}//end else if
					else{
						
						cTime = time;
						score += (combo-1) *100;
						combo = 0;
					}//end else
				}//end if
			}//end for
		}//end for
		if (!hit){
			//resets combo counter
			cTime = time;
			score += (combo-1) *100;
			combo = 0;
			//penalty for missing
			score-=10;
		}//end if
	}//end mouse pressed

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}



}
